import pandas as pd
import json
import numpy as np
from datetime import datetime

class Reporter:
    """
    回测报告生成器 - V7 (增加股债利差/ETF价格分析版本)
    - 支持3年、7年、10年多周期结果对比
    - 显示完整的回测指标
    - 在图表上标注交易信号
    - 新增股债利差和ETF价格时间序列图表
    - 详细显示每次交易的买卖比例
    - 使用Chart.js生成专业图表
    """
    def __init__(self, history_df, trade_records, best_params, metrics, multi_period_results=None):
        self.history_df = history_df.copy()
        self.trade_records = trade_records
        self.best_params = best_params
        self.metrics = metrics
        self.multi_period_results = multi_period_results or {}  # 存储多周期结果
        self.start_date = metrics.get('start_date', 'N/A')
        self.end_date = metrics.get('end_date', 'N/A')
        
        # 计算额外数据
        if not self.history_df.empty:
            self._calculate_benchmark_assets()
            self._prepare_chart_data()

    def _calculate_benchmark_assets(self):
        """计算基准策略的资产变化（100万全仓买入指数）"""
        initial_benchmark_capital = 1000000  # 与策略初始资金保持一致
        start_index_price = self.history_df['index_close'].iloc[0]
        self.history_df['benchmark_assets'] = (
            self.history_df['index_close'] / start_index_price * initial_benchmark_capital
        )
        
        # 计算回撤
        self.history_df['strategy_peak'] = self.history_df['total_assets'].cummax()
        self.history_df['strategy_drawdown'] = (
            (self.history_df['total_assets'] - self.history_df['strategy_peak']) / 
            self.history_df['strategy_peak'] * 100
        )
        
        self.history_df['benchmark_peak'] = self.history_df['benchmark_assets'].cummax()
        self.history_df['benchmark_drawdown'] = (
            (self.history_df['benchmark_assets'] - self.history_df['benchmark_peak']) / 
            self.history_df['benchmark_peak'] * 100
        )

    def _prepare_chart_data(self):
        """准备图表数据"""
        # 格式化日期
        self.dates = [d.strftime('%Y-%m-%d') for d in self.history_df.index]
        
        # 净值数据
        initial_capital = 1000000  # 假设初始资金100万
        self.equity_data = {
            'dates': self.dates,
            'strategy': (self.history_df['total_assets'] / initial_capital).round(4).tolist(),
            'benchmark': (self.history_df['benchmark_assets'] / initial_capital).round(4).tolist(),
            'position': (self.history_df['position_ratio'] * 100).round(2).tolist()
        }
        
        # 资产数据
        self.assets_data = {
            'dates': self.dates,
            'strategy_assets': (self.history_df['total_assets'] / 10000).round(2).tolist(),
            'benchmark_assets': (self.history_df['benchmark_assets'] / 10000).round(2).tolist(),
            'index_close': self.history_df['index_close'].round(2).tolist()
        }
        
        # 回撤数据
        self.drawdown_data = {
            'dates': self.dates,
            'strategy_dd': self.history_df['strategy_drawdown'].round(2).tolist(),
            'benchmark_dd': self.history_df['benchmark_drawdown'].round(2).tolist()
        }
        
        # 【新增】股债利差和ETF价格数据
        self.spread_etf_data = {
            'dates': self.dates,
            'spread': self.history_df.get('spread', [0] * len(self.dates)),  # 股债利差
            'etf_price': self.history_df.get('etf_close', [0] * len(self.dates))  # ETF价格
        }
        
        # 如果数据是Series，转换为list
        if hasattr(self.spread_etf_data['spread'], 'tolist'):
            self.spread_etf_data['spread'] = self.spread_etf_data['spread'].round(3).tolist()
        if hasattr(self.spread_etf_data['etf_price'], 'tolist'):
            self.spread_etf_data['etf_price'] = self.spread_etf_data['etf_price'].round(3).tolist()
        
        # 交易信号数据（从history_df中获取）
        if 'trade_signal' in self.history_df.columns:
            signals = self.history_df['trade_signal'].tolist()
            print(f"找到交易信号数据，信号数量: {len([s for s in signals if s != 0])}")
        else:
            signals = [0] * len(self.dates)
            print("警告: history_df中未找到trade_signal列，使用默认值0")
            
        self.signal_data = {
            'dates': self.dates,
            'signals': signals
        }
        
        # 【增强】交易标记点 - 增加详细的买卖比例信息
        self.trade_points = []
        self.detailed_trades = []  # 新增：详细交易记录
        
        if not self.trade_records.empty:
            for _, row in self.trade_records.iterrows():
                trade_date = pd.to_datetime(row['date']).strftime('%Y-%m-%d')
                if trade_date in self.dates:
                    idx = self.dates.index(trade_date)
                    equity_value = self.equity_data['strategy'][idx]
                    amount = row['shares'] * row['price']
                    
                    # 计算交易比例（相对于当前总资产）
                    current_assets = self.history_df['total_assets'].iloc[idx] if idx < len(self.history_df) else 1000000
                    trade_ratio = (amount / current_assets) * 100  # 转换为百分比
                    
                    # 获取当前的仓位比例
                    current_position = self.equity_data['position'][idx]
                    
                    # 获取股债利差和ETF价格
                    current_spread = self.spread_etf_data['spread'][idx] if idx < len(self.spread_etf_data['spread']) else 0
                    current_etf = self.spread_etf_data['etf_price'][idx] if idx < len(self.spread_etf_data['etf_price']) else 0
                    
                    # 买入用红色，卖出用绿色，清仓用橙色
                    if row['side'] == 'BUY':
                        color = '#ef4444'  # 红色 - 买入
                        symbol = '🔺'
                        action_desc = f"买入 {trade_ratio:.2f}%"
                    elif row['side'] == 'SELL':
                        color = '#22c55e'  # 绿色 - 卖出
                        symbol = '🔻'
                        action_desc = f"卖出 {trade_ratio:.2f}%"
                    else:  # LIQUIDATE
                        color = '#f59e0b'  # 橙色 - 清仓
                        symbol = '⏹️'
                        action_desc = f"清仓 {trade_ratio:.2f}%"
                    
                    # 交易点标记（用于图表显示）
                    trade_point = {
                        'x': trade_date,
                        'y': equity_value,
                        'type': row['side'],
                        'amount': round(amount, 0),
                        'shares': round(row['shares'], 2),
                        'price': round(row['price'], 2),
                        'trade_ratio': round(trade_ratio, 2),
                        'position_after': round(current_position, 2),
                        'spread': round(current_spread, 3),
                        'etf_price': round(current_etf, 3),
                        'color': color,
                        'symbol': symbol,
                        'action_desc': action_desc
                    }
                    self.trade_points.append(trade_point)
                    
                    # 详细交易记录（用于表格显示）
                    detailed_trade = {
                        'date': trade_date,
                        'action': row['side'],
                        'shares': round(row['shares'], 2),
                        'price': round(row['price'], 2),
                        'amount': round(amount, 0),
                        'trade_ratio': round(trade_ratio, 2),
                        'position_before': round(current_position - (trade_ratio if row['side'] == 'BUY' else -trade_ratio), 2),
                        'position_after': round(current_position, 2),
                        'spread': round(current_spread, 3),
                        'etf_price': round(current_etf, 3),
                        'assets_before': round(current_assets / 10000, 2),
                        'description': f"{action_desc}，仓位：{round(current_position, 2)}%"
                    }
                    self.detailed_trades.append(detailed_trade)

    def _generate_detailed_trades_table_html(self):
        """生成详细交易记录表格"""
        if not self.detailed_trades:
            return "<p style='text-align: center; color: #94a3b8; padding: 60px;'>暂无交易记录</p>"
        
        styles = """
        <style>
            .trades-table-container { margin: 30px auto; max-width: 95%; overflow-x: auto; }
            .trades-table { 
                width: 100%; 
                border-collapse: collapse; 
                background: white;
                border-radius: 12px;
                overflow: hidden;
                box-shadow: 0 8px 25px rgba(0,0,0,0.1);
                font-size: 13px;
            }
            .trades-table th { 
                background: linear-gradient(135deg, #059669 0%, #047857 100%);
                color: white; 
                padding: 15px 12px; 
                text-align: center; 
                font-weight: 700;
                font-size: 12px;
                text-transform: uppercase;
                letter-spacing: 0.5px;
                position: sticky;
                top: 0;
                z-index: 10;
            }
            .trades-table td { 
                padding: 12px 12px; 
                text-align: center; 
                border-bottom: 1px solid #e2e8f0;
                font-size: 12px;
                vertical-align: middle;
            }
            .trades-table tr:last-child td { 
                border-bottom: none; 
            }
            .trades-table tr:nth-child(even) { 
                background: #f8fafc; 
            }
            .trades-table tr:hover { 
                background: #e0f2fe; 
                transition: background-color 0.2s ease;
            }
            .action-buy { 
                background: linear-gradient(135deg, #fee2e2, #fecaca); 
                color: #dc2626; 
                font-weight: 700; 
                border-radius: 6px; 
                padding: 4px 8px;
            }
            .action-sell { 
                background: linear-gradient(135deg, #dcfce7, #bbf7d0); 
                color: #16a34a; 
                font-weight: 700; 
                border-radius: 6px; 
                padding: 4px 8px;
            }
            .action-liquidate { 
                background: linear-gradient(135deg, #fef3c7, #fde68a); 
                color: #d97706; 
                font-weight: 700; 
                border-radius: 6px; 
                padding: 4px 8px;
            }
            .ratio-positive { color: #059669; font-weight: 700; }
            .ratio-negative { color: #dc2626; font-weight: 700; }
            .ratio-neutral { color: #3b82f6; font-weight: 600; }
            .amount-large { background: #fef7ff; border-left: 3px solid #8b5cf6; }
            .spread-high { background: #ecfdf5; color: #059669; font-weight: 600; }
            .spread-low { background: #fef2f2; color: #dc2626; font-weight: 600; }
        </style>
        """
        
        table_html = """
        <div class="trades-table-container">
            <table class="trades-table">
                <thead>
                    <tr>
                        <th>交易日期</th>
                        <th>操作类型</th>
                        <th>交易股数</th>
                        <th>成交价格</th>
                        <th>交易金额<br>(万元)</th>
                        <th>交易比例<br>(%)</th>
                        <th>交易前仓位<br>(%)</th>
                        <th>交易后仓位<br>(%)</th>
                        <th>股债利差</th>
                        <th>ETF价格</th>
                        <th>资产规模<br>(万元)</th>
                        <th>操作说明</th>
                    </tr>
                </thead>
                <tbody>
        """
        
        for trade in self.detailed_trades:
            # 确定操作类型的样式
            action_class = f"action-{trade['action'].lower()}"
            
            # 确定交易比例的颜色
            if trade['trade_ratio'] > 2:
                ratio_class = "ratio-positive"
            elif trade['trade_ratio'] > 1:
                ratio_class = "ratio-neutral"
            else:
                ratio_class = "ratio-negative"
            
            # 确定股债利差的颜色
            spread_class = "spread-high" if trade['spread'] > 5 else "spread-low"
            
            # 确定金额大小的样式
            amount_class = "amount-large" if trade['amount'] > 50000 else ""
            
            table_html += f"""
            <tr class="{amount_class}">
                <td>{trade['date']}</td>
                <td><span class="{action_class}">{trade['action']}</span></td>
                <td>{trade['shares']:,}</td>
                <td>¥{trade['price']:.2f}</td>
                <td>¥{trade['amount']/10000:.1f}</td>
                <td class="{ratio_class}">{trade['trade_ratio']:.2f}%</td>
                <td>{trade['position_before']:.1f}%</td>
                <td>{trade['position_after']:.1f}%</td>
                <td class="{spread_class}">{trade['spread']:.3f}</td>
                <td>¥{trade['etf_price']:.3f}</td>
                <td>¥{trade['assets_before']:.1f}</td>
                <td style="text-align: left; max-width: 200px;">{trade['description']}</td>
            </tr>
            """
        
        table_html += """
                </tbody>
            </table>
        </div>
        """
        
        return styles + table_html

    def _generate_multi_period_comparison_html(self):
        """生成多周期对比表格"""
        if not self.multi_period_results:
            return ""
            
        styles = """
        <style>
            .period-comparison { margin: 30px auto; max-width: 95%; }
            .comparison-table { 
                width: 100%; 
                border-collapse: collapse; 
                background: white;
                border-radius: 12px;
                overflow: hidden;
                box-shadow: 0 8px 25px rgba(0,0,0,0.1);
            }
            .comparison-table th { 
                background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
                color: white; 
                padding: 18px 15px; 
                text-align: center; 
                font-weight: 700;
                font-size: 14px;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }
            .comparison-table td { 
                padding: 15px 15px; 
                text-align: center; 
                border-bottom: 1px solid #e2e8f0;
                font-size: 14px;
            }
            .comparison-table tr:last-child td { 
                border-bottom: none; 
            }
            .comparison-table tr:nth-child(even) { 
                background: #f8fafc; 
            }
            .metric-name { 
                text-align: left !important; 
                font-weight: 600; 
                color: #475569;
                background: #f1f5f9 !important;
            }
            .positive-value { color: #059669; font-weight: 700; }
            .negative-value { color: #dc2626; font-weight: 700; }
            .neutral-value { color: #3b82f6; font-weight: 600; }
        </style>
        """
        
        # 定义需要显示的指标
        metrics_to_show = [
            ('回测周期', 'period_label'),
            ('总收益率', 'total_return'),
            ('年化收益率(CAGR)', 'annualized_return_cagr'),
            ('年化收益率(算术)', 'annualized_return_arithmetic'),
            ('基准年化收益', 'benchmark_annual_return'),
            ('年化波动率', 'annual_volatility'),
            ('夏普比率', 'sharpe_ratio'),
            ('最大回撤', 'max_drawdown'),
            ('Calmar比率', 'calmar_ratio'),
            ('总交易次数', 'total_trades')
        ]
        
        table_html = """
        <div class="period-comparison">
            <h2 style="text-align: center; color: #1e293b; margin-bottom: 25px; font-size: 28px;">📊 多周期回测结果对比</h2>
            <table class="comparison-table">
                <thead>
                    <tr>
                        <th style="text-align: left;">指标</th>
        """
        
        # 添加各周期的列标题
        period_labels = []
        for period_key in ['3y_avg', '7y_avg', 'full']:
            if period_key in self.multi_period_results:
                if period_key == '3y_avg':
                    period_labels.append('3年滚动平均')
                elif period_key == '7y_avg':
                    period_labels.append('7年滚动平均')
                else:
                    period_labels.append('全周期(10年)')
                table_html += f"<th>{period_labels[-1]}</th>"
        
        table_html += """
                    </tr>
                </thead>
                <tbody>
        """
        
        # 添加各指标行
        for metric_name, metric_key in metrics_to_show:
            if metric_key == 'period_label':
                continue
                
            table_html += f'<tr><td class="metric-name">{metric_name}</td>'
            
            for period_key in ['3y_avg', '7y_avg', 'full']:
                if period_key in self.multi_period_results:
                    metrics = self.multi_period_results[period_key]
                    value = metrics.get(metric_key, 'N/A')
                    
                    if isinstance(value, (int, float)) and not np.isnan(value):
                        # 确定颜色类
                        if metric_key in ['total_return', 'annualized_return_cagr', 'annualized_return_arithmetic', 'benchmark_annual_return']:
                            color_class = 'positive-value' if value > 0 else 'negative-value'
                            display_value = f"{value:.2%}"
                        elif metric_key == 'max_drawdown':
                            color_class = 'negative-value' if value < -0.05 else 'positive-value'
                            display_value = f"{value:.2%}"
                        elif metric_key in ['sharpe_ratio', 'calmar_ratio']:
                            color_class = 'positive-value' if value > 1 else ('neutral-value' if value > 0 else 'negative-value')
                            display_value = f"{value:.3f}"
                        elif metric_key == 'annual_volatility':
                            color_class = 'negative-value' if value > 0.25 else ('neutral-value' if value > 0.15 else 'positive-value')
                            display_value = f"{value:.2%}"
                        elif metric_key == 'total_trades':
                            color_class = 'neutral-value'
                            display_value = f"{int(value)}"
                        else:
                            color_class = 'neutral-value'
                            display_value = f"{value:.3f}"
                    else:
                        color_class = 'neutral-value'
                        display_value = 'N/A'
                    
                    table_html += f'<td class="{color_class}">{display_value}</td>'
            
            table_html += '</tr>'
        
        table_html += """
                </tbody>
            </table>
        </div>
        """
        
        return styles + table_html

    def _generate_metrics_summary_html(self):
        """生成核心指标面板（使用全周期数据）"""
        styles = """
        <style>
            .metrics-container { margin: 20px auto; max-width: 95%; }
            .metrics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; margin-bottom: 30px; }
            .metric-card { 
                background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
                border-radius: 16px; 
                box-shadow: 0 4px 20px rgba(0,0,0,0.08); 
                padding: 30px; 
                text-align: center; 
                border: 1px solid #e2e8f0; 
                transition: all 0.3s ease;
                position: relative;
                overflow: hidden;
            }
            .metric-card::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                height: 4px;
                background: linear-gradient(90deg, #3b82f6, #8b5cf6);
            }
            .metric-card:hover { 
                transform: translateY(-5px); 
                box-shadow: 0 12px 40px rgba(0,0,0,0.15); 
            }
            .metric-card h3 { 
                margin: 0 0 15px; 
                font-size: 16px; 
                color: #64748b; 
                font-weight: 600; 
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }
            .metric-card p { 
                margin: 0 0 12px; 
                font-size: 36px; 
                font-weight: 800; 
                color: #1e293b;
                text-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            .metric-description { 
                font-size: 13px; 
                color: #94a3b8; 
                line-height: 1.5; 
                margin-top: 10px; 
            }
            .positive { color: #059669 !important; }
            .negative { color: #dc2626 !important; }
            .neutral { color: #3b82f6 !important; }
        </style>
        """
        
        # 指标配置 - 显示所有backtest_engine的指标
        metrics_config = [
            {'key': 'total_return', 'name': '总收益率', 'format': 'percent', 'icon': '📈', 'description': '策略期末资产相对初始资产的增长率'},
            {'key': 'annualized_return_cagr', 'name': '年化收益率(CAGR)', 'format': 'percent', 'icon': '🚀', 'description': '复合年增长率，考虑复利效应'},
            {'key': 'annualized_return_arithmetic', 'name': '年化收益率(算术)', 'format': 'percent', 'icon': '📊', 'description': '算术平均年化收益率'},
            {'key': 'benchmark_total_return', 'name': '基准总收益', 'format': 'percent', 'icon': '📈', 'description': '基准策略的总收益率'},
            {'key': 'benchmark_annual_return', 'name': '基准年化收益', 'format': 'percent', 'icon': '📊', 'description': '基准策略的年化收益率'},
            {'key': 'annual_volatility', 'name': '年化波动率', 'format': 'percent', 'icon': '🌊', 'description': '策略收益的标准差，衡量风险水平'},
            {'key': 'sharpe_ratio', 'name': '夏普比率', 'format': 'number', 'icon': '⚖️', 'description': '风险调整后收益，值越高越好'},
            {'key': 'max_drawdown', 'name': '最大回撤', 'format': 'percent', 'icon': '📉', 'description': '策略历史最大亏损幅度'},
            {'key': 'calmar_ratio', 'name': 'Calmar比率', 'format': 'number', 'icon': '🎯', 'description': '年化收益率除以最大回撤的比值'},
            {'key': 'total_trades', 'name': '总交易次数', 'format': 'integer', 'icon': '🔄', 'description': '回测期间的买卖交易总数'}
        ]

        cards_html = ""
        for config in metrics_config:
            value = self.metrics.get(config['key'], 'N/A')
            
            if isinstance(value, (int, float)) and not np.isnan(value):
                # 确定颜色
                if config['key'] in ['total_return', 'annualized_return_cagr', 'annualized_return_arithmetic', 'benchmark_total_return', 'benchmark_annual_return']:
                    color_class = 'positive' if value > 0 else 'negative'
                elif config['key'] == 'max_drawdown':
                    color_class = 'negative' if value < -0.1 else 'positive'
                elif config['key'] in ['sharpe_ratio', 'calmar_ratio']:
                    color_class = 'positive' if value > 1 else ('neutral' if value > 0 else 'negative')
                elif config['key'] == 'annual_volatility':
                    color_class = 'negative' if value > 0.3 else ('neutral' if value > 0.15 else 'positive')
                else:
                    color_class = 'neutral'
                
                # 格式化显示
                if config['format'] == 'percent':
                    display_value = f"{value:.2%}"
                elif config['format'] == 'integer':
                    display_value = f"{int(value)}"
                else:
                    display_value = f"{value:.3f}"
            else:
                color_class = 'neutral'
                display_value = 'N/A'

            cards_html += f"""
            <div class="metric-card">
                <h3>{config['icon']} {config['name']}</h3>
                <p class="{color_class}">{display_value}</p>
                <div class="metric-description">{config['description']}</div>
            </div>
            """
        
        return f"""
        {styles}
        <div class="metrics-container">
            <h2 style="text-align: center; color: #1e293b; margin-bottom: 30px; font-size: 28px;">📊 全周期核心指标({self.start_date} ~ {self.end_date})</h2>
            <div class='metrics-grid'>{cards_html}</div>
        </div>
        """

    def _generate_strategy_details_html(self):
        """生成策略详情"""
        date_info_html = f"""
        <div style="text-align: center; margin: 20px 0; padding: 25px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 16px; color: white; box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3);">
            <h3 style="margin: 0; font-size: 22px; text-shadow: 0 2px 4px rgba(0,0,0,0.3);">🗓️ 回测周期: {self.start_date} 至 {self.end_date}</h3>
        </div>
        """
        
        styles = """
        <style>
            .strategy-container { margin: 20px auto; max-width: 95%; }
            .details-grid { display: grid; grid-template-columns: 1fr 2fr; gap: 30px; margin-top: 25px; }
            .details-box { 
                background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
                padding: 30px; 
                border-radius: 16px; 
                border: 1px solid #e2e8f0; 
                box-shadow: 0 4px 20px rgba(0,0,0,0.08);
                position: relative;
            }
            .details-box::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                height: 4px;
                background: linear-gradient(90deg, #f59e0b, #ef4444);
                border-radius: 16px 16px 0 0;
            }
            .params-table { width: 100%; border-collapse: collapse; margin-top: 15px; }
            .params-table td { padding: 15px 18px; border-bottom: 1px solid #f1f5f9; font-size: 14px; }
            .params-table tr:last-child td { border-bottom: none; }
            .param-key { color: #475569; font-weight: 600; width: 45%; }
            .param-value { 
                color: #1e293b; 
                font-family: 'SF Mono', Consolas, monospace; 
                background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
                padding: 10px 15px; 
                border-radius: 8px;
                font-weight: 500;
            }
            .formula-box { 
                background: linear-gradient(135deg, #fef7ff 0%, #f3e8ff 100%);
                padding: 25px; 
                border-radius: 12px; 
                margin: 20px 0; 
                border-left: 5px solid #8b5cf6;
                box-shadow: 0 2px 10px rgba(139, 92, 246, 0.1);
            }
            .formula-title { 
                color: #7c3aed; 
                font-weight: 700; 
                margin-bottom: 15px; 
                display: flex; 
                align-items: center; 
                font-size: 16px;
                gap: 8px;
            }
            .formula-content { 
                color: #475569; 
                line-height: 1.7; 
                font-size: 14px;
            }
            .highlight-value { 
                background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
                padding: 4px 10px; 
                border-radius: 6px; 
                font-weight: 700;
                color: #92400e;
                box-shadow: 0 1px 3px rgba(251, 191, 36, 0.3);
            }
        </style>
        """
        
        # 参数表格
        params_html = "<h3 style='color: #1e40af; display: flex; align-items: center; gap: 8px;'>⚙️ 策略参数配置</h3><table class='params-table'>"
        for key, value in self.best_params.items():
            if isinstance(value, (list, tuple)) and len(str(value)) > 50:
                value_str = f"{str(value)[:47]}..."
            elif isinstance(value, float):
                value_str = f"{value:.4f}"
            else:
                value_str = str(value)
            params_html += f"<tr><td class='param-key'>{key}</td><td class='param-value'>{value_str}</td></tr>"
        params_html += "</table>"

        # 交易逻辑（具体数值）- 更新为买卖独立因子
        p = self.best_params
        buy_th = p.get('buy_threshold', 0)
        sell_th = p.get('sell_threshold', 0)
        # 【更新】新的参数名
        initial_buy_ratio = p.get('initial_buy_ratio', 0)
        initial_sell_ratio = p.get('initial_sell_ratio', 0)
        buy_base_factor = p.get('buy_base_factor', 1.0)
        sell_base_factor = p.get('sell_base_factor', 1.0)
        # 【修改】买卖独立的因子参数
        buy_spread_f = p.get('buy_spread_factor', 0)
        sell_spread_f = p.get('sell_spread_factor', 0)
        buy_etf_f = p.get('buy_etf_factor', 0)
        sell_etf_f = p.get('sell_etf_factor', 0)
        max_ratio = p.get('max_trade_ratio', 0)

        logic_html = f"""
        <h3 style='color: #1e40af; display: flex; align-items: center; gap: 8px;'>🎯 交易逻辑 (买卖独立因子版本)</h3>

        <div class='formula-box'>
            <div class='formula-title'>📈 买入触发条件</div>
            <div class='formula-content'>
                当股债利差 ≥ <span class='highlight-value'>{buy_th:.3f}</span> 时，系统触发买入信号<br>
                初始买入比率：<span class='highlight-value'>{initial_buy_ratio:.2%}</span><br>
                基础调整因子：<span class='highlight-value'>{buy_base_factor:.2f}</span><br>
                买入利差因子：<span class='highlight-value'>{buy_spread_f:.4f}</span><br>
                买入ETF因子：<span class='highlight-value'>{buy_etf_f:.6f}</span>
            </div>
        </div>

        <div class='formula-box'>
            <div class='formula-title'>📉 卖出触发条件</div>
            <div class='formula-content'>
                当股债利差 ≤ <span class='highlight-value'>{sell_th:.3f}</span> 时，系统触发卖出信号<br>
                初始卖出比率：<span class='highlight-value'>{initial_sell_ratio:.2%}</span><br>
                基础调整因子：<span class='highlight-value'>{sell_base_factor:.2f}</span><br>
                卖出利差因子：<span class='highlight-value'>{sell_spread_f:.4f}</span><br>
                卖出ETF因子：<span class='highlight-value'>{sell_etf_f:.6f}</span>
            </div>
        </div>

        <div class='formula-box'>
            <div class='formula-title'>⚖️ 交易比例计算公式（买卖独立版本）</div>
            <div class='formula-content'>
                <strong>核心公式：</strong><br>
                <div style='background: #f8fafc; padding: 10px; border-radius: 5px; margin: 8px 0; font-family: monospace;'>
                    最终交易比例 = 初始比率 × 调整因子<br>
                    调整因子使用买入/卖出各自独立的参数
                </div>
                <strong>买入计算：</strong><br>
                1. 价差偏离度 = 当前股债利差 - {buy_th:.3f}<br>
                2. 买入调整因子 = <span class='highlight-value'>{buy_base_factor:.2f}</span> + (偏离度 × <span class='highlight-value'>{buy_spread_f:.4f}</span>) + (ETF价格 × <span class='highlight-value'>{buy_etf_f:.6f}</span>)<br>
                3. 买入交易比例 = <span class='highlight-value'>{initial_buy_ratio:.2%}</span> × 买入调整因子<br><br>
                <strong>卖出计算：</strong><br>
                1. 价差偏离度 = {sell_th:.3f} - 当前股债利差<br>
                2. 卖出调整因子 = <span class='highlight-value'>{sell_base_factor:.2f}</span> + (偏离度 × <span class='highlight-value'>{sell_spread_f:.4f}</span>) + (ETF价格 × <span class='highlight-value'>{sell_etf_f:.6f}</span>)<br>
                3. 卖出交易比例 = <span class='highlight-value'>{initial_sell_ratio:.2%}</span> × 卖出调整因子<br><br>
                4. 最终限制：min(计算比例, <span class='highlight-value'>{max_ratio:.1%}</span>)
            </div>
        </div>

        <div class='formula-box'>
            <div class='formula-title'>💡 买卖独立因子策略说明</div>
            <div class='formula-content'>
                • <strong>独立性优势</strong>：买入和卖出现在拥有各自独立的敏感度参数<br>
                • <strong>初始比率</strong>：设定基础交易规模（如0.3%）<br>
                • <strong>调整因子</strong>：根据市场条件动态放大或缩小交易规模<br>
                • <strong>买入利差因子</strong>：控制买入时对股债利差变化的敏感度<br>
                • <strong>卖出利差因子</strong>：控制卖出时对股债利差变化的敏感度<br>
                • <strong>买入/卖出ETF因子</strong>：分别控制对ETF价格的响应程度<br>
                • <strong>精确控制</strong>：可以针对不同市场条件优化买卖行为
            </div>
        </div>
        """
        
        return f"""
        {styles}
        <div class="strategy-container">
            <h2 style="text-align: center; color: #1e293b; margin-bottom: 25px; font-size: 28px;">📋 策略配置详情</h2>
            {date_info_html}
            <div class='details-grid'>
                <div class='details-box'>{params_html}</div>
                <div class='details-box'>{logic_html}</div>
            </div>
        </div>
        """

    def generate_report(self, filename="enhanced_report_v7.html"):
        """生成增强版报告（包含多周期对比、股债利差/ETF价格图表和详细交易记录）"""
        print("正在生成包含股债利差/ETF价格分析的增强版回测报告...")
        
        multi_period_html = self._generate_multi_period_comparison_html()
        metrics_html = self._generate_metrics_summary_html()
        strategy_details_html = self._generate_strategy_details_html()
        detailed_trades_html = self._generate_detailed_trades_table_html()

        # 准备所有图表数据
        chart_data = {
            'equity': self.equity_data,
            'assets': self.assets_data,
            'drawdown': self.drawdown_data,
            'trades': self.trade_points,
            'signals': self.signal_data,
            'spread_etf': self.spread_etf_data  # 新增股债利差和ETF价格数据
        }

        # 交易统计数据
        trade_stats = {}
        if not self.trade_records.empty:
            trade_counts = self.trade_records['side'].value_counts()
            trade_stats = {
                'labels': trade_counts.index.tolist(),
                'data': trade_counts.values.tolist(),
                'colors': ['#3b82f6', '#ef4444', '#10b981', '#f59e0b'][:len(trade_counts)]
            }

        # 完整的HTML页面
        html_content = f"""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>量化策略回测报告 - 股债利差/ETF分析版</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/date-fns@2.29.3/index.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@2.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
    <style>
        * {{ box-sizing: border-box; margin: 0; padding: 0; }}
        body {{ 
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif;
            padding: 20px; 
            color: #1e293b;
        }}
        .container {{
            max-width: 1400px;
            margin: 0 auto;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(10px);
        }}
        .main-title {{ 
            text-align: center; 
            color: #1e293b; 
            margin: 30px 0 50px; 
            font-size: 3em; 
            font-weight: 800; 
            text-shadow: 0 4px 8px rgba(0,0,0,0.1);
            background: linear-gradient(135deg, #667eea, #764ba2);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }}
        .section {{ margin: 50px 0; }}
        .chart-container {{
            background: white;
            border-radius: 16px;
            padding: 30px;
            margin: 30px 0;
            box-shadow: 0 8px 30px rgba(0,0,0,0.08);
            border: 1px solid #e2e8f0;
        }}
        .chart-title {{
            font-size: 24px;
            font-weight: 700;
            color: #1e293b;
            margin-bottom: 20px;
            text-align: center;
            padding-bottom: 15px;
            border-bottom: 3px solid #e2e8f0;
        }}
        .chart-grid {{
            display: grid;
            grid-template-columns: 2fr 1fr;
            gap: 30px;
            margin: 30px 0;
        }}
        .chart-canvas {{
            position: relative;
            height: 400px;
            width: 100%;
        }}
        .chart-canvas.large {{ height: 500px; }}
        .footer {{
            text-align: center;
            margin: 60px 0 30px;
            padding: 30px;
            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
            border-radius: 16px;
            color: #64748b;
            border: 1px solid #e2e8f0;
        }}
        @media (max-width: 768px) {{
            .chart-grid {{ grid-template-columns: 1fr; }}
            .main-title {{ font-size: 2em; }}
            .container {{ padding: 20px; }}
        }}
    </style>
</head>
<body>
    <div class="container">
        <h1 class="main-title">📊 量化策略回测报告</h1>
        
        <div class="section">
            {multi_period_html}
        </div>
        
        <div class="section">
            {metrics_html}
        </div>
        
        <div class="section">
            {strategy_details_html}
        </div>
        
        <div class="section">
            <div class="chart-container">
                <div class="chart-title">📈 策略净值曲线对比（含交易信号）</div>
                <div class="chart-canvas large">
                    <canvas id="equityChart"></canvas>
                </div>
            </div>
        </div>
        
        <div class="section">
            <div class="chart-container">
                <div class="chart-title">💰 资产变化对比 (策略 vs 全仓买指数)</div>
                <div class="chart-canvas large">
                    <canvas id="assetsChart"></canvas>
                </div>
            </div>
        </div>
        
        <div class="section">
            <div class="chart-container">
                <div class="chart-title">📈 股债利差 & ETF价格走势（策略核心因子）</div>
                <div class="chart-canvas large">
                    <canvas id="spreadEtfChart"></canvas>
                </div>
            </div>
        </div>
        
        <div class="section">
            <div class="chart-container">
                <div class="chart-title">📊 交易信号强度变化</div>
                <div class="chart-canvas">
                    <canvas id="signalChart"></canvas>
                </div>
            </div>
        </div>
        
        <div class="section">
            <div class="chart-grid">
                <div class="chart-container">
                    <div class="chart-title">📉 回撤风险分析</div>
                    <div class="chart-canvas">
                        <canvas id="drawdownChart"></canvas>
                    </div>
                </div>
                <div class="chart-container">
                    <div class="chart-title">🔄 交易统计分布</div>
                    <div class="chart-canvas">
                        <canvas id="tradeChart"></canvas>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="section">
            <div class="chart-container">
                <div class="chart-title">📋 详细交易记录表</div>
                {detailed_trades_html}
            </div>
        </div>
        
        <div class="footer">
            <p><strong>报告生成时间:</strong> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
            <p>© 量化策略回测系统 V7 - 股债利差/ETF分析增强版</p>
        </div>
    </div>

    <script>
        // 图表数据
        const chartData = {json.dumps(chart_data, ensure_ascii=False)};
        const tradeStats = {json.dumps(trade_stats, ensure_ascii=False)};
        
        // 通用图表配置
        Chart.defaults.font.family = "'-apple-system', 'BlinkMacSystemFont', 'Segoe UI', sans-serif";
        Chart.defaults.font.size = 12;
        
        // 1. 净值曲线图（含交易信号标记）
        const equityCtx = document.getElementById('equityChart').getContext('2d');
        const buySignals = chartData.trades.filter(t => t.type === 'BUY');
        const sellSignals = chartData.trades.filter(t => t.type === 'SELL');
        const liquidateSignals = chartData.trades.filter(t => t.type === 'LIQUIDATE');
        
        new Chart(equityCtx, {{
            type: 'line',
            data: {{
                labels: chartData.equity.dates,
                datasets: [{{
                    label: '策略净值',
                    data: chartData.equity.strategy,
                    borderColor: '#3b82f6',
                    backgroundColor: 'rgba(59, 130, 246, 0.1)',
                    borderWidth: 3,
                    fill: true,
                    tension: 0.4,
                    pointRadius: 0,
                    pointHoverRadius: 6
                }}, {{
                    label: '基准净值',
                    data: chartData.equity.benchmark,
                    borderColor: '#ef4444',
                    backgroundColor: 'rgba(239, 68, 68, 0.05)',
                    borderWidth: 2,
                    borderDash: [5, 5],
                    fill: false,
                    tension: 0.4,
                    pointRadius: 0,
                    pointHoverRadius: 6
                }},{{
                    label: '买入信号',
                    data: buySignals,
                    backgroundColor: '#ef4444',
                    borderColor: '#ef4444',
                    pointRadius: 6,
                    pointHoverRadius: 10,
                    showLine: false,
                    type: 'scatter'
                }},{{
                    label: '卖出信号',
                    data: sellSignals,
                    backgroundColor: '#22c55e',
                    borderColor: '#22c55e',
                    pointRadius: 6,
                    pointHoverRadius: 10,
                    showLine: false,
                    type: 'scatter'
                }},{{
                    label: '平仓信号',
                    data: liquidateSignals,
                    backgroundColor: '#f59e0b',
                    borderColor: '#f59e0b',
                    pointRadius: 8,
                    pointHoverRadius: 12,
                    showLine: false,
                    type: 'scatter'
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                interaction: {{
                    intersect: false,
                    mode: 'index'
                }},
                plugins: {{
                    legend: {{
                        position: 'top',
                        labels: {{
                            usePointStyle: true,
                            padding: 20,
                            font: {{ size: 14, weight: 'bold' }}
                        }}
                    }},
                    tooltip: {{
                        backgroundColor: 'rgba(255, 255, 255, 0.95)',
                        titleColor: '#1e293b',
                        bodyColor: '#475569',
                        borderColor: '#e2e8f0',
                        borderWidth: 1,
                        cornerRadius: 8,
                        displayColors: true,
                        callbacks: {{
                            afterBody: function(tooltipItems) {{
                                const scatterTooltipItem = tooltipItems.find(item => item.dataset.type === 'scatter');
                                if (scatterTooltipItem) {{
                                    const trade = scatterTooltipItem.raw;
                                    return [
                                        `交易类型: ${{trade.type}}`,
                                        `交易比例: ${{trade.trade_ratio}}%`,
                                        `交易金额: ¥${{trade.amount.toLocaleString()}}`,
                                        `交易后仓位: ${{trade.position_after}}%`,
                                        `股债利差: ${{trade.spread}}`,
                                        `ETF价格: ¥${{trade.etf_price}}`
                                    ];
                                }}
                                return [];
                            }}
                        }}
                    }}
                }},
                scales: {{
                    x: {{
                        type: 'time',
                        time: {{ unit: 'month' }},
                        grid: {{ color: '#f1f5f9' }},
                        ticks: {{ color: '#64748b' }}
                    }},
                    y: {{
                        grid: {{ color: '#f1f5f9' }},
                        ticks: {{ 
                            color: '#64748b',
                            callback: function(value) {{
                                return value.toFixed(3);
                            }}
                        }}
                    }}
                }}
            }}
        }});
        
        // 2. 资产对比图
        const assetsCtx = document.getElementById('assetsChart').getContext('2d');
        new Chart(assetsCtx, {{
            type: 'line',
            data: {{
                labels: chartData.assets.dates,
                datasets: [{{
                    label: '策略总资产 (万元)',
                    data: chartData.assets.strategy_assets,
                    borderColor: '#059669',
                    backgroundColor: 'rgba(5, 150, 105, 0.1)',
                    borderWidth: 3,
                    fill: true,
                    tension: 0.4,
                    pointRadius: 0,
                    yAxisID: 'y'
                }}, {{
                    label: '基准资产 (万元)',
                    data: chartData.assets.benchmark_assets,
                    borderColor: '#dc2626',
                    backgroundColor: 'rgba(220, 38, 38, 0.05)',
                    borderWidth: 2,
                    borderDash: [5, 5],
                    fill: false,
                    tension: 0.4,
                    pointRadius: 0,
                    yAxisID: 'y'
                }}, {{
                    label: '指数点位',
                    data: chartData.assets.index_close,
                    borderColor: '#6b7280',
                    borderWidth: 1,
                    borderDash: [2, 2],
                    fill: false,
                    tension: 0.4,
                    pointRadius: 0,
                    yAxisID: 'y1'
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                interaction: {{
                    intersect: false,
                    mode: 'index'
                }},
                plugins: {{
                    legend: {{
                        position: 'top',
                        labels: {{
                            usePointStyle: true,
                            padding: 20
                        }}
                    }}
                }},
                scales: {{
                    x: {{
                        type: 'time',
                        time: {{ unit: 'month' }},
                        grid: {{ color: '#f1f5f9' }}
                    }},
                    y: {{
                        type: 'linear',
                        display: true,
                        position: 'left',
                        title: {{ display: true, text: '资产 (万元)' }},
                        grid: {{ color: '#f1f5f9' }}
                    }},
                    y1: {{
                        type: 'linear',
                        display: true,
                        position: 'right',
                        title: {{ display: true, text: '指数点位' }},
                        grid: {{ drawOnChartArea: false }}
                    }}
                }}
            }}
        }});
        
        // 3. 【新增】股债利差和ETF价格图表
        const spreadEtfCtx = document.getElementById('spreadEtfChart').getContext('2d');
        
        // 为交易点在股债利差图上添加标记
        const tradePointsForSpread = chartData.trades.map(trade => ({{
            x: trade.x,
            y: trade.spread,
            trade_info: trade
        }}));
        
        new Chart(spreadEtfCtx, {{
            type: 'line',
            data: {{
                labels: chartData.spread_etf.dates,
                datasets: [{{
                    label: '股债利差',
                    data: chartData.spread_etf.spread,
                    borderColor: '#8b5cf6',
                    backgroundColor: 'rgba(139, 92, 246, 0.1)',
                    borderWidth: 2,
                    fill: true,
                    tension: 0.4,
                    pointRadius: 0,
                    pointHoverRadius: 4,
                    yAxisID: 'y'
                }}, {{
                    label: 'ETF价格 (¥)',
                    data: chartData.spread_etf.etf_price,
                    borderColor: '#f59e0b',
                    backgroundColor: 'rgba(245, 158, 11, 0.1)',
                    borderWidth: 2,
                    fill: false,
                    tension: 0.4,
                    pointRadius: 0,
                    pointHoverRadius: 4,
                    yAxisID: 'y1'
                }}, {{
                    label: '交易点位 (股债利差)',
                    data: tradePointsForSpread,
                    backgroundColor: function(context) {{
                        const trade = context.raw?.trade_info;
                        return trade ? trade.color : '#666';
                    }},
                    borderColor: function(context) {{
                        const trade = context.raw?.trade_info;
                        return trade ? trade.color : '#666';
                    }},
                    pointRadius: function(context) {{
                        return context.raw?.trade_info ? 8 : 0;
                    }},
                    pointHoverRadius: 12,
                    showLine: false,
                    type: 'scatter',
                    yAxisID: 'y'
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                interaction: {{
                    intersect: false,
                    mode: 'index'
                }},
                plugins: {{
                    legend: {{
                        position: 'top',
                        labels: {{
                            usePointStyle: true,
                            padding: 20
                        }}
                    }},
                    tooltip: {{
                        backgroundColor: 'rgba(255, 255, 255, 0.95)',
                        titleColor: '#1e293b',
                        bodyColor: '#475569',
                        borderColor: '#e2e8f0',
                        borderWidth: 1,
                        cornerRadius: 8,
                        callbacks: {{
                            afterBody: function(tooltipItems) {{
                                const scatterTooltipItem = tooltipItems.find(item => item.dataset.type === 'scatter');
                                if (scatterTooltipItem && scatterTooltipItem.raw.trade_info) {{
                                    const trade = scatterTooltipItem.raw.trade_info;
                                    return [
                                        `${{trade.action_desc}}`,
                                        `交易金额: ¥${{trade.amount.toLocaleString()}}`,
                                        `ETF价格: ¥${{trade.etf_price}}`,
                                        `交易后仓位: ${{trade.position_after}}%`
                                    ];
                                }}
                                return [];
                            }}
                        }}
                    }}
                }},
                scales: {{
                    x: {{
                        type: 'time',
                        time: {{ unit: 'month' }},
                        grid: {{ color: '#f1f5f9' }},
                        ticks: {{ color: '#64748b' }}
                    }},
                    y: {{
                        type: 'linear',
                        display: true,
                        position: 'left',
                        title: {{ display: true, text: '股债利差' }},
                        grid: {{ color: '#f1f5f9' }},
                        ticks: {{ color: '#64748b' }}
                    }},
                    y1: {{
                        type: 'linear',
                        display: true,
                        position: 'right',
                        title: {{ display: true, text: 'ETF价格 (¥)' }},
                        grid: {{ drawOnChartArea: false }},
                        ticks: {{ color: '#64748b' }}
                    }}
                }}
            }}
        }});
        
        // 4. 交易信号图
        const signalCtx = document.getElementById('signalChart').getContext('2d');
        new Chart(signalCtx, {{
            type: 'line',
            data: {{
                labels: chartData.signals.dates,
                datasets: [{{
                    label: '交易信号强度',
                    data: chartData.signals.signals,
                    borderColor: '#8b5cf6',
                    backgroundColor: 'rgba(139, 92, 246, 0.1)',
                    borderWidth: 2,
                    fill: true,
                    tension: 0.4,
                    pointRadius: 0,
                    pointHoverRadius: 4
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                plugins: {{
                    legend: {{ position: 'top' }},
                    tooltip: {{
                        callbacks: {{
                            label: function(context) {{
                                const value = context.parsed.y;
                                if (value > 0) {{
                                    return `买入信号: ${{(value * 100).toFixed(2)}}%`;
                                }} else if (value < 0) {{
                                    return `卖出信号: ${{(Math.abs(value) * 100).toFixed(2)}}%`;
                                }} else {{
                                    return '无交易信号';
                                }}
                            }}
                        }}
                    }}
                }},
                scales: {{
                    x: {{
                        type: 'time',
                        time: {{ unit: 'month' }},
                        grid: {{ color: '#f1f5f9' }}
                    }},
                    y: {{
                        grid: {{ color: '#f1f5f9' }},
                        ticks: {{
                            callback: function(value) {{
                                return (value * 100).toFixed(1) + '%';
                            }}
                        }}
                    }}
                }}
            }}
        }});
        
        // 5. 回撤分析图
        const drawdownCtx = document.getElementById('drawdownChart').getContext('2d');
        new Chart(drawdownCtx, {{
            type: 'line',
            data: {{
                labels: chartData.drawdown.dates,
                datasets: [{{
                    label: '策略回撤 (%)',
                    data: chartData.drawdown.strategy_dd,
                    borderColor: '#ef4444',
                    backgroundColor: 'rgba(239, 68, 68, 0.2)',
                    borderWidth: 2,
                    fill: true,
                    tension: 0.4,
                    pointRadius: 0
                }}, {{
                    label: '基准回撤 (%)',
                    data: chartData.drawdown.benchmark_dd,
                    borderColor: '#f97316',
                    backgroundColor: 'rgba(249, 115, 22, 0.1)',
                    borderWidth: 2,
                    borderDash: [5, 5],
                    fill: false,
                    tension: 0.4,
                    pointRadius: 0
                }}]
            }},
            options: {{
                responsive: true,
                maintainAspectRatio: false,
                plugins: {{
                    legend: {{ position: 'top' }}
                }},
                scales: {{
                    x: {{
                        type: 'time',
                        time: {{ unit: 'month' }},
                        grid: {{ color: '#f1f5f9' }}
                    }},
                    y: {{
                        max: 5,
                        grid: {{ color: '#f1f5f9' }},
                        ticks: {{
                            callback: function(value) {{
                                return value + '%';
                            }}
                        }}
                    }}
                }}
            }}
        }});
        
        // 6. 交易统计饼图
        if (tradeStats.labels && tradeStats.labels.length > 0) {{
            const tradeCtx = document.getElementById('tradeChart').getContext('2d');
            new Chart(tradeCtx, {{
                type: 'doughnut',
                data: {{
                    labels: tradeStats.labels,
                    datasets: [{{
                        data: tradeStats.data,
                        backgroundColor: tradeStats.colors,
                        borderWidth: 3,
                        borderColor: '#ffffff'
                    }}]
                }},
                options: {{
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {{
                        legend: {{
                            position: 'bottom',
                            labels: {{ padding: 20 }}
                        }},
                        tooltip: {{
                            callbacks: {{
                                label: function(context) {{
                                    const total = context.dataset.data.reduce((a, b) => a + b, 0);
                                    const percentage = ((context.parsed / total) * 100).toFixed(1);
                                    return context.label + ': ' + context.parsed + ' (' + percentage + '%)';
                                }}
                            }}
                        }}
                    }}
                }}
            }});
        }} else {{
            document.getElementById('tradeChart').parentElement.innerHTML = '<p style="text-align: center; color: #94a3b8; padding: 60px;">暂无交易数据</p>';
        }}
        
        // 响应式处理
        window.addEventListener('resize', function() {{
            Chart.helpers.each(Chart.instances, function(instance) {{
                instance.resize();
            }});
        }});
    </script>
</body>
</html>
        """

        with open(filename, "w", encoding="utf-8") as f:
            f.write(html_content)
        
        print(f"✅ 股债利差/ETF分析增强版回测报告已生成: {filename}")
        print(f"📊 新增功能:")
        print(f"   - 股债利差和ETF价格时间序列图表")
        print(f"   - 交易点在股债利差图上的精确标记")
        print(f"   - 详细交易记录表格（包含买卖比例、股债利差、ETF价格）")
        print(f"   - 交易tooltip显示完整交易信息")
        return filename